package cn.hsw.manage.permission.service.impl;

import cn.hsw.component.auth.service.AuthService;
import cn.hsw.component.core.util.BeanUtil;
import cn.hsw.component.core.util.Validator;
import cn.hsw.manage.constant.ManageConstant;
import cn.hsw.manage.permission.entity.Permission;
import cn.hsw.manage.permission.mapper.PermissionMapper;
import cn.hsw.manage.permission.service.PermissionService;
import cn.hsw.manage.permission.vo.*;
import cn.hsw.manage.role.mapper.RoleMapper;
import cn.hsw.manage.role.service.RoleService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author 李子木
 * @since 2021-11-03 08:56:37
 */
@Service
public class PermissionServiceImpl extends ServiceImpl<PermissionMapper, Permission> implements PermissionService {

    @Autowired
    RoleService roleService;

    @Autowired
    AuthService authService;

    @Override
    public Set<String> getPermissionsSet(Long userPid) {
        return baseMapper.getPermissionsSetByUserPid(userPid,ManageConstant.PERMISSION_TYPE_API);
    }

    @Override
    public void add(PermissionVO permissionVO) {
        /*验证不通类型的参数*/
        checkType(permissionVO.getType(),permissionVO.getParentPid());

        Permission permissionModel = BeanUtil.copyProperties(permissionVO, Permission.class);
        baseMapper.insert(permissionModel);
    }

    @Override
    public void delete(Long pid) {
        Permission permissionModel = baseMapper.selectById(pid);
        Validator.validateNotNull(permissionModel,"不存在或已删除");
        baseMapper.deleteById(pid);
    }

    @Override
    public void edit(Long pid, PermissionVO permissionVO) {
        Permission permissionModel = baseMapper.selectById(pid);
        Validator.validateNotNull(permissionModel,"不存在或已删除");

        /*验证不通类型的参数*/
        checkType(permissionModel.getType(),permissionVO.getParentPid());
        List<Permission> tempList = baseMapper.findByparentPid(permissionModel.getPid());
        List<Long> subPidS = subPidS(tempList, new ArrayList<>());
        subPidS.add(permissionModel.getPid());

        Validator.validateContains(subPidS,permissionVO.getParentPid(),"不能选自己或自己的子节点作为父节点");

        if(Validator.isNotNull(permissionVO.getName())){
            permissionModel.setName(permissionVO.getName());
        }

        if(Validator.isNotNull(permissionVO.getUrl())){
            permissionModel.setUrl(permissionVO.getUrl());
        }

        if(Validator.isNotNull(permissionVO.getState())){
            Validator.validateContains(new String[]{ManageConstant.PERMISSION_STATE_SHOW+"",ManageConstant.PERMISSION_STATE_NOT_SHOW+""}
                    ,permissionVO.getState()+"","状态必须是"+ManageConstant.PERMISSION_STATE_SHOW+ManageConstant.PERMISSION_STATE_NOT_SHOW);
            permissionModel.setState(permissionVO.getState());
        }

        if(Validator.isNotNull(permissionVO.getCode())){

            Permission codePermissionModel = baseMapper.findByCode(permissionVO.getCode());
            if(Validator.isNotNull(codePermissionModel)){
                //不为空的情况下 只能和自己用的一个才可以继续用
                Validator.validateEqual(codePermissionModel.getPid(),permissionModel.getPid(),"权限code已经存在");
            }
            permissionModel.setCode(permissionVO.getCode());
        }

        if(Validator.isNotNull(permissionVO.getSort())){
            permissionModel.setSort(permissionVO.getSort());
        }
        if(Validator.isNotNull(permissionVO.getRemark())){
            permissionModel.setRemark(permissionVO.getRemark());
        }

        this.updateById(permissionModel);
    }

    @Override
    public void editState(Long pid, Integer state) {
        Permission permissionModel = baseMapper.selectById(pid);
        Validator.validateNotNull(permissionModel,"不存在或已删除");
        Validator.validateContains(new String[]{ManageConstant.PERMISSION_STATE_SHOW+"",ManageConstant.PERMISSION_STATE_NOT_SHOW+""}
                ,state+"","状态必须是"+ManageConstant.PERMISSION_STATE_SHOW+ManageConstant.PERMISSION_STATE_NOT_SHOW);
        permissionModel.setState(state);
        baseMapper.updateById(permissionModel);
        /* @TODO 权限信息变更，删除权限缓存*/
    }

    @Override
    public List<PermissionTreeVO> tree(int type) {
        List<Integer> typeList = new ArrayList<>();
        if(type == 3){
            typeList.add(ManageConstant.PERMISSION_TYPE_MENU);
            typeList.add(ManageConstant.PERMISSION_TYPE_PAGE);
            typeList.add(ManageConstant.PERMISSION_TYPE_API);
        }else{
            typeList.add(ManageConstant.PERMISSION_TYPE_MENU);
            typeList.add(ManageConstant.PERMISSION_TYPE_PAGE);
        }

        List<PermissionTreeVO> list = baseMapper.selectByTypeIn(typeList);

        Map<Long, List<PermissionTreeVO>> nodeByParentIdMap = list.stream().collect(Collectors.groupingBy(permission -> {
            if(Validator.isEmpty(permission.getParentPid())){
                return 0L;
            }else{
                return permission.getParentPid();
            }
        }));
        list.forEach(permission -> permission.setChild(nodeByParentIdMap.get(permission.getPid())));
        List<PermissionTreeVO> permissionTreeVOList = list.stream().filter(permission -> Validator.isNull(permission.getParentPid())).collect(Collectors.toList());
        return permissionTreeVOList;
    }

    @Override
    public MenuVo menu() {
        Long currUserPid = authService.getCurrUserPid();

        List<MenuInfoVo> list = baseMapper.findByTypeNotAndStateAndUserPid(ManageConstant.PERMISSION_TYPE_API, ManageConstant.PERMISSION_STATE_SHOW,currUserPid);
        /*tree*/
        Map<Long, List<MenuInfoVo>> nodeByParentIdMap = list.stream().collect(Collectors.groupingBy(menuInfo -> {
            if(Validator.isEmpty(menuInfo.getParentPid())){
                return 0L;
            }else{
                return menuInfo.getParentPid();
            }
        }));
        list.forEach(menuInfo -> menuInfo.setChild(nodeByParentIdMap.get(menuInfo.getPid())));
        List<MenuInfoVo> menuInfoList = list.stream().filter(menuInfo -> Validator.isNull(menuInfo.getParentPid())).collect(Collectors.toList());

        MenuVo menuVo = new MenuVo();
        menuVo.setMenuInfo(menuInfoList);
        HomeInfoVo homeInfo = new HomeInfoVo();
        homeInfo.setHref("page/welcome.html?t=1");
        homeInfo.setTitle("首页");
        menuVo.setHomeInfo(homeInfo);
        LogoInfoVo logoInfo = new LogoInfoVo();
        logoInfo.setHref("");
        logoInfo.setImage("images/logo.png");
        logoInfo.setTitle("Hsw强制储蓄");
        menuVo.setLogoInfo(logoInfo);
        return menuVo;
    }

    @Override
    public Permission findByCode(String code) {
        return baseMapper.findByCode(code);
    }

    @Override
    public PermissionDetailVO findByPid(Long pid) {
        return baseMapper.findByPid(pid);
    }

    /**
     * 不同类型下的值验证
     * @param type 类型
     * @param parentPid 父ID
     */
    private void checkType(int type,Long parentPid){
        switch (type){
            case ManageConstant.PERMISSION_TYPE_MENU:

                break;
            case ManageConstant.PERMISSION_TYPE_PAGE:
                Validator.validateNotEmpty(parentPid,"页面必须在菜单下");
                Validator.validateEqual(ManageConstant.PERMISSION_TYPE_MENU,baseMapper.selectById(parentPid).getType(),"页面必须在菜单下");
                break;
            case ManageConstant.PERMISSION_TYPE_API:
                Validator.validateNotEmpty(parentPid,"功能必须在页面下");
                Validator.validateEqual(ManageConstant.PERMISSION_TYPE_PAGE,baseMapper.selectById(parentPid).getType(),"功能必须在页面下");
                break;
            default:

        }
    }
    private List<Long> subPidS(List<Permission> list,List<Long> subPidS){
        list.forEach(permissionModel -> {
            subPidS.add(permissionModel.getPid());
            List<Permission> tempList = baseMapper.findByparentPid(permissionModel.getPid());
            if(tempList.size()>0){
                subPidS(tempList,subPidS);
            }

        });
        return subPidS;
    }
}
